package com.easylinkin.linkappapi.premeeting.service.impl;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.easylinkin.linkappapi.common.model.RequestModel;
import com.easylinkin.linkappapi.premeeting.entity.RailPreMeeting;
import com.easylinkin.linkappapi.premeeting.mapper.RailPreMeetingMapper;
import com.easylinkin.linkappapi.premeeting.service.RailPreMeetingService;

import com.easylinkin.linkappapi.premeeting.vo.RailPreMeetingQueryVo;
import com.easylinkin.linkappapi.premeeting.vo.RailPreMeetingVo;
import com.easylinkin.linkappapi.premeeting.vo.RailPreMeetingCalendarVo;
import com.easylinkin.linkappapi.premeeting.vo.RailPreMeetingCalendarQueryVo;
import com.easylinkin.linkappapi.premeeting.vo.RailPreMeetingDateGridVo;
import com.easylinkin.linkappapi.premeeting.vo.RailPreMeetingGridSwitchVo;
import com.easylinkin.linkappapi.tenant.entity.LinkappTenant;
import com.easylinkin.linkappapi.tenant.mapper.LinkappTenantMapper;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import java.util.HashMap;
import java.util.Map;
import com.easylinkin.linkappapi.penetsecuremanage.mapper.RailLinkappGridManagementInfoMapper;
import com.easylinkin.linkappapi.penetsecuremanage.entity.RailLinkappGridManagementInfo;
import com.easylinkin.linkappapi.security.context.LinkappUserContextProducer;
import org.springframework.stereotype.Service;


import javax.annotation.Resource;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;

/**
 * <p>
 * 班前会表 服务实现类
 * </p>
 *
 * @author zl
 * @since 2025-06-30
 */
@Service
public class RailPreMeetingServiceImpl extends ServiceImpl<RailPreMeetingMapper, RailPreMeeting> implements RailPreMeetingService {

    @Resource
    private LinkappUserContextProducer linkappUserContextProducer;

    @Resource
    private RailLinkappGridManagementInfoMapper gridManagementInfoMapper;

    @Autowired
    private LinkappTenantMapper linkappTenantMapper;

    @Autowired
    private ObjectMapper objectMapper;

    /**
     * 增加
     * @param railPreMeeting
     */
    @Override
    public void insert(RailPreMeeting railPreMeeting) {
        // 设置基本属性
        this.setBase(railPreMeeting);
        this.save(railPreMeeting);
    }

    /**
     * 根据id编辑
     * @param railPreMeeting
     */
    @Override
    public void updateOne(RailPreMeeting railPreMeeting) {
        // 设置基本属性
        this.setBase(railPreMeeting);
        this.updateById(railPreMeeting);
    }

    /**
     * @Description: 删除班前会（包含批量删除）
     * @author zl
     * @date 2025-06-30
     */
    @Override
    public void delBatch(List<Long> ids) {
        // 逻辑删除
        baseMapper.deleteBatchIds(ids);
    }

    @Override
    public IPage<RailPreMeetingVo> queryListByPage(RequestModel<RailPreMeetingQueryVo> requestModel) {
        Page page = requestModel.getPage();
        RailPreMeetingQueryVo queryVo = requestModel.getCustomQueryParams();
        // 项目id 过滤
        queryVo.setTenantId(linkappUserContextProducer.getNotNullCurrent().getTenantId());
//        //开时间不为空设置为当天开始时间
//        if (queryVo.getMeetingTimeStart() != null) {
//            queryVo.setMeetingTimeStart(DateUtil.beginOfDay(queryVo.getMeetingTimeStart()));
//        }
//        //结束时间不为空设置为当天结束时间
//        if (queryVo.getMeetingTimeEnd() != null) {
//            queryVo.setMeetingTimeEnd(DateUtil.endOfDay(queryVo.getMeetingTimeEnd()));
//        }
        IPage<RailPreMeetingVo> result = baseMapper.queryListByPage(page, queryVo);
        return result;
    }

    /**
     * @Description: 根据id查询班前会详情
     * @author zl
     * @date 2025-06-30
     */
    @Override
    public RailPreMeetingVo findById(String id) {
        return baseMapper.findById(id);
    }

    /**
     * @Description: 获取班前会日历数据
     * @author kyf
     * @date 2025-06-30
     */
    @Override
    public List<RailPreMeetingCalendarVo> getCalendarData(RailPreMeetingCalendarQueryVo queryVo) {
        // 设置租户ID
        String tenantId = linkappUserContextProducer.getNotNullCurrent().getTenantId();
        queryVo.setTenantId(tenantId);

        // 1. 查询当前网格点
        LambdaQueryWrapper<RailLinkappGridManagementInfo> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(RailLinkappGridManagementInfo::getTenantId, tenantId)
               .select(RailLinkappGridManagementInfo::getId);
        List<RailLinkappGridManagementInfo> allGrids = gridManagementInfoMapper.selectList(wrapper);
        Set<Long> allGridIds = allGrids.stream()
            .map(RailLinkappGridManagementInfo::getId)
            .collect(Collectors.toSet());

        // 2. 按条件查询班前会数据，按天、按网格统计
        List<RailPreMeetingDateGridVo> meetingData = baseMapper.getCalendarData(queryVo);

        // 3. 按日期分组班前会数据（只包含有班前会记录的网格点）
        Map<String, Set<Long>> dateCompletedGridMap = meetingData.stream()
            .collect(Collectors.groupingBy(
                RailPreMeetingDateGridVo::getDate,
                Collectors.mapping(
                    RailPreMeetingDateGridVo::getGridId,
                    Collectors.toSet()
                )
            ));

        // 4. 解析年月参数
        String[] parts = queryVo.getYearMonth().split("-");
        int year = Integer.parseInt(parts[0]);
        int month = Integer.parseInt(parts[1]);

        // 5. 生成该月份的所有日期
        List<RailPreMeetingCalendarVo> calendarList = new ArrayList<>();
        LocalDate startDate = LocalDate.of(year, month, 1);
        LocalDate endDate = startDate.withDayOfMonth(startDate.lengthOfMonth());
        LocalDate currentDate = LocalDate.now();

        // 6. 遍历该月份的每一天，代码里判断每个网格点在当天是否有数据
        for (LocalDate date = startDate; !date.isAfter(endDate); date = date.plusDays(1)) {
            RailPreMeetingCalendarVo calendarVo = new RailPreMeetingCalendarVo();
            String dateStr = date.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
            calendarVo.setDate(dateStr);

            // 判断日期状态
            if (date.isAfter(currentDate)) {
                // 未到时间的日期
                calendarVo.setDateStatus(3);
            } else {
                // 获取该日期有班前会记录的网格点
                Set<Long> completedGridsOnDate = dateCompletedGridMap.getOrDefault(dateStr, new HashSet<>());

                // 代码里判断：每一个网格点在当天是否有数据
                int completedCount = 0;
                for (Long gridId : allGridIds) {
                    if (completedGridsOnDate.contains(gridId)) {
                        completedCount++;
                    }
                }

                // 根据完成情况判断状态
                if (completedCount == 0) {
                    // 所有网格点都没有班前会记录
                    calendarVo.setDateStatus(0);
                } else if (completedCount == allGridIds.size()) {
                    // 所有网格点都有班前会记录
                    calendarVo.setDateStatus(2);
                } else {
                    // 部分网格点有班前会记录
                    calendarVo.setDateStatus(1);
                }
            }

            calendarList.add(calendarVo);
        }

        return calendarList;
    }

    /**
     * @Description: 获取网格点切换数据（显示所有网格点及其数据状态）
     * @author kyf
     * @date 2025-06-30
     */
    @Override
    public List<RailPreMeetingGridSwitchVo> getGridSwitchData(Date startTime, Date endTime) {
        String tenantId = linkappUserContextProducer.getNotNullCurrent().getTenantId();
        return baseMapper.getGridSwitchData(tenantId, startTime, endTime);
    }

    /**
     * @Description: 获取班前会按年月导出数据
     * @author kyf
     * @date 2025-06-30
     */
    @Override
    public Map<String, Object> getExportDataByYearMonth(String yearMonth) throws JsonProcessingException {
        // 构建查询条件
        RailPreMeetingQueryVo queryVo = new RailPreMeetingQueryVo();
        queryVo.setTenantId(linkappUserContextProducer.getNotNullCurrent().getTenantId());

        DateTime dateTime = DateUtil.parse(yearMonth, "yyyy-MM");
        queryVo.setMeetingTimeStart(DateUtil.beginOfMonth(dateTime));
        queryVo.setMeetingTimeEnd(DateUtil.endOfMonth(dateTime));


        // 构建分页请求（不分页，获取所有数据）
        RequestModel<RailPreMeetingQueryVo> requestModel = new RequestModel<>();
        requestModel.setCustomQueryParams(queryVo);

        requestModel.setPage(new Page<>(1,-1));

        // 复用分页查询接口获取数据
        IPage<RailPreMeetingVo> result = this.queryListByPage(requestModel);
        List<RailPreMeetingVo> records = result.getRecords();

        // 组织导出数据
        Map<String, Object> map = new HashMap<>();
        LinkappTenant query = new LinkappTenant();
        query.setId(queryVo.getTenantId());
        LinkappTenant linkappTenant = linkappTenantMapper.selectLinkappTenant(query);

        // 组织返回数据
//        String jsonStr = JSONUtil.toJsonStr(records);
        String string = objectMapper.writeValueAsString(records);
        JSONArray array = JSONUtil.parseArray(string);
        //将 meetingTime 转成 date
        array.forEach(item -> {
            JSONObject jsonObject = (JSONObject) item;
            jsonObject.put("meetingTime", DateUtil.parse(jsonObject.getStr("meetingTime")));
        });

        map.put("list", array);
        map.put("timeStr", DateUtil.format(dateTime, "yyyy年MM月"));
        map.put("projectName", linkappTenant.getPlatformProjectName()+"项目");
        map.put("yearMonth", yearMonth);

        return map;
    }

    /**
     * 设置基本属性
     */
    private void setBase(RailPreMeeting railPreMeeting) {
        // 设置租户ID等基本属性
        railPreMeeting.setTenantId(linkappUserContextProducer.getNotNullCurrent().getTenantId());

        if (railPreMeeting.getId() == null) {
            // 新增时设置创建信息
            railPreMeeting.setCreatorId(linkappUserContextProducer.getNotNullCurrent().getId());
            railPreMeeting.setCreateTime(new Date());
        } else {
            // 更新时设置修改信息
            railPreMeeting.setModifyId(linkappUserContextProducer.getNotNullCurrent().getId());
            railPreMeeting.setModifyTime(new Date());
        }
    }
}
